package com.yida.system.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yida.common.core.constant.CacheConstants;
import com.yida.common.core.enums.DelFlagEnum;
import com.yida.common.core.enums.EnableTypeEnum;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.redis.service.RedisService;
import com.yida.system.api.domain.SysBlackList;
import com.yida.system.api.domain.SysWhiteList;
import com.yida.system.domain.request.SysWhiteListEditRequest;
import com.yida.system.mapper.SysBlackListMapper;
import com.yida.system.mapper.SysWhiteListMapper;
import com.yida.system.service.ISysWhiteListService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * 系统白名单Service业务层处理
 * 
 * @author wws
 * @date 2023-03-22
 */
@Service
// @RequiredArgsConstructor
public class SysWhiteListServiceImpl implements ISysWhiteListService {

    @Autowired
    private SysWhiteListMapper sysWhiteListMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SysBlackListMapper sysBlackListMapper;

    /**
     * 查询系统白名单
     * 
     * @param id 系统白名单主键
     * @return 系统白名单
     */
    @Override
    public SysWhiteList selectSysWhiteListById(Long id) {
        return sysWhiteListMapper.selectSysWhiteListById(id);
    }

    /**
     * 查询系统白名单列表
     * 
     * @param sysWhiteList 系统白名单
     * @return 系统白名单
     */
    @Override
    public List<SysWhiteList> selectSysWhiteListList(SysWhiteList sysWhiteList) {
        return sysWhiteListMapper.selectSysWhiteListList(sysWhiteList);
    }

    /**
     * 新增系统白名单
     * 
     * @param ipAddress IP地址
     * @return 结果
     */
    @Override
    public int insertSysWhiteList(String ipAddress) {
        // 判断该IP是否存在白名单中
        SysWhiteList sysWhiteList = getInfoByIpAddress(ipAddress);
        if (ObjectUtil.isNotEmpty(sysWhiteList)) {
            throw new ServiceException("当前IP地址已存在，请勿重复添加");
        }
        // 判断该IP是否存在黑名单中
        SysBlackList blackList = new SysBlackList();
        blackList.setIpAddress(ipAddress);
        SysBlackList sysBlackList = sysBlackListMapper.selectSysBlackList(blackList);
        if (ObjectUtil.isNotEmpty(sysBlackList)) {
            // 删除黑名单中数据
            sysBlackList.setDelFlag(DelFlagEnum.DELETE.getType());
            if (1 != sysBlackListMapper.updateSysBlackList(sysBlackList)) {
                throw new ServiceException("当前IP地址存在在黑名单，删除失败");
            }
            // 删除黑名单缓存
            if (redisService.hasKey(CacheConstants.BLACK_LIST + CacheConstants.REDIS_SUFFIX + ipAddress)) {
                redisService.deleteObject(CacheConstants.BLACK_LIST + CacheConstants.REDIS_SUFFIX + ipAddress);
            }
        }
        // 处理白名单参数
        sysWhiteList = new SysWhiteList();
        sysWhiteList.setIpAddress(ipAddress);
        // 保存白名单信息
        int result = sysWhiteListMapper.insertSysWhiteList(sysWhiteList);
        if (1 != result) {
            throw new ServiceException("白名单保存失败");
        }
        // 加入缓存
        Set<String> ipAddressSet = new HashSet<>(1);
        ipAddressSet.add(sysWhiteList.getIpAddress());
        redisService.setCacheSet(CacheConstants.WHITE_LIST_KEY, ipAddressSet);
        return result;
    }

    /**
     * 修改系统白名单
     * 
     * @param editRequest 系统白名单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSysWhiteList(SysWhiteListEditRequest editRequest) {
        // 查询白名单信息
        SysWhiteList sysWhiteList = sysWhiteListMapper.selectSysWhiteListById(editRequest.getId());
        if (ObjectUtil.isEmpty(sysWhiteList)) {
            throw new ServiceException("未查询到对应白名单信息");
        }
        // 拷贝参数
        BeanUtil.copyProperties(editRequest, sysWhiteList);
        // 更新白名单信息
        int result = sysWhiteListMapper.updateSysWhiteList(sysWhiteList);
        if (1 != result) {
            throw new ServiceException("白名单修改失败");
        }
        // 判断白名单启用状态存入或删除缓存
        if (EnableTypeEnum.LOCK.getType().equals(sysWhiteList.getStatus())) {
            // 删除缓存
            redisService.deleteSet(CacheConstants.WHITE_LIST_KEY, sysWhiteList.getIpAddress());
        } else if (EnableTypeEnum.UNLOCK.getType().equals(sysWhiteList.getStatus())) {
            Set<String> ipAddress = new HashSet<>(1);
            ipAddress.add(sysWhiteList.getIpAddress());
            // 加入缓存
            redisService.setCacheSet(CacheConstants.WHITE_LIST_KEY, ipAddress);
        } else {
            throw new ServiceException("白名单启用状态异常");
        }
        return result;
    }

    /**
     * 批量删除系统白名单
     * 
     * @param ids 需要删除的系统白名单主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSysWhiteListByIds(Long[] ids) {
        if (ObjectUtil.isEmpty(ids)) {
            throw new ServiceException("请选中要删除的白名单数据");
        }
        for (Long id : ids) {
            // 查询白名单信息
            SysWhiteList sysWhiteList = sysWhiteListMapper.selectSysWhiteListById(id);
            if (ObjectUtil.isEmpty(sysWhiteList)) {
                throw new ServiceException("未查询到对应白名单信息");
            }
            // 删除白名单信息
            sysWhiteList.setDelFlag(DelFlagEnum.DELETE.getType());
            if (1 != sysWhiteListMapper.updateSysWhiteList(sysWhiteList)) {
                throw new ServiceException("白名单删除失败");
            }
            // 删除缓存
            redisService.deleteSet(CacheConstants.WHITE_LIST_KEY, sysWhiteList.getIpAddress());
        }
        return 1;
    }

    /**
     * 删除系统白名单信息
     * 
     * @param id 系统白名单主键
     * @return 结果
     */
    @Override
    public int deleteSysWhiteListById(Long id) {
        return sysWhiteListMapper.deleteSysWhiteListById(id);
    }

    /**
     * 根据ip地址查询白名单信息
     * 
     * @param ipAddress
     * @return
     */

    private SysWhiteList getInfoByIpAddress(String ipAddress) {
        SysWhiteList sysWhiteList = new SysWhiteList();
        sysWhiteList.setIpAddress(ipAddress);
        return sysWhiteListMapper.selectSysWhiteList(sysWhiteList);
    }
}
